<?php

namespace App\Third\Service\Wx;


use App\Common\Service\BaseService;

/**
 * http://doc.wuuxiang.com/showdoc/web/#/35?page_id=401
 * Class WxSystemService
 * @package App\Third\Service\Wx
 */

class WxSystemService extends BaseService
{
    /**
     * 集团id
     * @var string
     */
    protected  $productId;
    /**
     * 微信公众号id
     * @var string
     */
    protected $mpId;
    /**
     * @var string
     */
    protected $version;
    /**
     * @var string
     */
    protected $public_key;
    /**
     * @var string
     */
    protected $pc_base_url;
    /**
     * @var string
     */
    protected $mobile_base_url;

    /**
     * WxSystemService constructor.
     */
    public function __construct()
    {
        parent::__construct();
        if(config('app_env') == 'dev'){
            $this->productId = '1000003877';
            $this->mpId = 'gh_70ab1b63a54b';
            $this->version = '1.0.0';
            $this->public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCUMcXm11i/+iyeAkMkEZuR6dvlj6ooU4RSu6XNaDyNMB0wn2u1dNqwtV4nvLAwiymW28sdm7Rg9pegZLkUGMPox/MNuX71Y1MjHE4BQXfxYMuyLHwU36qG2eG9pTUDIcKyA01VzKxTqZPQkfeauZbyAtsdeGLkOuMldKCRG8s4kQIDAQAB';
            $this->pc_base_url = 'https://cscrm7.wuuxiang.com/crm7api/';
            $this->mobile_base_url = 'https://cscrm7.wuuxiang.com/crm7gsapi/wxapi/';
        }else{
            $this->productId = '1000012123';
            $this->mpId = 'gh_70ab1b63a54b';
            $this->version = '1.0.0';
            $this->public_key = 'MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQC/7FAHaCFTE7GZqxRC6XZwfCEm0PJpbFPxP+0YicVJcoCX0p/FYwnqmGa9VGdPZPS9zvSqGhiXccQS90nSeBv/xtUIzPII27Cq2jDI/TgOh5/xD4XgSwqa+W5KAI8VSTFe3HmPPoUhv85sNuvAqcziT91PdRmuEUwyfZQG2AcjVQIDAQAB';
            $this->pc_base_url = 'https://scrm.wuuxiang.com/crm7api/';
            $this->mobile_base_url = 'https://scrm.wuuxiang.com/crm7gsapi/wxapi/';
        }
    }
    /**
     * @param $method
     * @param $api_name
     * @param $temp_data
     * @return bool|mixed|string
     */
    public function pcCrmApi($method, $api_name, $temp_data) {

        $pem = chunk_split($this->public_key,64,"\n");//转换为pem格式的公钥
        $pem = "-----BEGIN PUBLIC KEY-----\n".$pem."-----END PUBLIC KEY-----\n";
        $new_public_key = openssl_pkey_get_public($pem);//获取公钥内容
        $post_data = array();
        $post_data['productId'] = $this->productId;
        $post_data['version'] = $this->version;
        if($temp_data){
            $encrypt_data = WxSystemService::encrypt117($temp_data,$new_public_key);
        }
        $post_data['sign'] = $encrypt_data;
        if($method == 'GET') {
            $api_name .= "?sign=$encrypt_data&productId=$this->productId&version=$this->version";
        }
        $post_url = $this->pc_base_url.$api_name;
        if ($method == 'POST'){
            $api_return_data = WxSystemService::_http_post_json($method, $post_url,json_encode($post_data));
            $return_data = json_decode($api_return_data[1],true);
        }else{
            $api_return_data = WxSystemService::http_post($method, $post_url,json_encode($post_data));
            $return_data = $api_return_data;
        }
        return $return_data;
    }

    /**
     * @param $method
     * @param $api_name
     * @param string $openId
     * @param $temp_data
     * @return mixed
     */
    public function tiantaiCrmApi($method, $api_name, $openId='', $temp_data){
        $pem = chunk_split($this->public_key,64,"\n");//转换为pem格式的公钥
        $pem = "-----BEGIN PUBLIC KEY-----\n".$pem."-----END PUBLIC KEY-----\n";
        $new_public_key = openssl_pkey_get_public($pem);//获取公钥内容
        $post_data = array();
        $post_data['productId'] = $this->productId;
        $post_data['mpId'] = $this->mpId;
        $post_data['openId'] = $openId;
        if($temp_data){
            /*加密数据*/
            $encrypt_data = self::encrypt117($temp_data,$new_public_key);
            $post_data['data'] =$encrypt_data;
        }
        if($method == 'GET') {
            $api_name .= "?sign=$encrypt_data&productId=$this->productId&version=$this->version";
        }
        $post_url = $this->mobile_base_url.$api_name;
        $api_return_data = self::_http_post_json($method, $post_url, json_encode($post_data));
        $return_data = json_decode($api_return_data[1],true);
        if ($return_data['code']==200) {
            $decrypt_data = self::decrypt128($return_data['content'],$new_public_key);
            $return_data['data'] = json_decode($decrypt_data,true);
        }
        return $return_data;
    }
    /**
     * @param $method
     * @param $url
     * @param $jsonStr
     * @return array|string
     */
    private static function _http_post_json($method, $url, $jsonStr)
    {
        if(substr($url,0,5) == 'https' ){
            return self::post_curls($url,$jsonStr);
        }
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        if($method == 'POST') {
            curl_setopt($ch, CURLOPT_POST, 1);
            curl_setopt($ch, CURLOPT_POSTFIELDS, $jsonStr);

            curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
            curl_setopt($ch, CURLOPT_HTTPHEADER, array(
                    'Content-Type: application/json; charset=utf-8',
                    'Content-Length: ' . strlen($jsonStr)
                )
            );
        }
        $response = curl_exec($ch);
        $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        return array($httpCode, $response);
    }

    /**
     * @param $url
     * @param $post
     * @return array
     */
    private static function post_curls($url, $post)
    {
        $curl = curl_init(); // 启动一个CURL会话
        curl_setopt($curl, CURLOPT_URL, $url); // 要访问的地址
        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, 0); // 对认证证书来源的检查
        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, 2); // 从证书中检查SSL加密算法是否存在
        curl_setopt($curl, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']); // 模拟用户使用的浏览器
        curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1); // 使用自动跳转
        curl_setopt($curl, CURLOPT_AUTOREFERER, 1); // 自动设置Referer
        curl_setopt($curl, CURLOPT_POST, 1); // 发送一个常规的Post请求
        curl_setopt($curl, CURLOPT_POSTFIELDS, $post); // Post提交的数据包
        curl_setopt($curl, CURLOPT_TIMEOUT, 30); // 设置超时限制防止死循环
        curl_setopt($curl, CURLOPT_HEADER, 0); // 显示返回的Header区域内容
        curl_setopt($curl, CURLOPT_HTTPHEADER, array(
            'Content-Type: application/json; charset=utf-8',
            'Content-Length: ' . strlen($post)
        ));
        curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1); // 获取的信息以文件流的形式返回
        $response = curl_exec($curl);
        $httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
        curl_close($curl);
        return array($httpCode, $response);

    }

    /**
     * file_get_contents模拟网络请求
     * @param string $method 请求方法
     * @param string $url 请求方法
     * @param array $options 请求参数[]
     * @return bool|string
     */
    private static function http_post($method, $url, $options)
    {
        $data = @json_encode($options);  //把参数转换成json数据
        $aContext = array('http' => array('method' => $method,
            'timeout' => 30,
            'header'  => 'Content-type: application/json:charset=UTF-8',
            'content' => $data ));
        $cxContext  = stream_context_create($aContext);
        $result = @file_get_contents($url,false,$cxContext);
        return json_decode($result, true);

    }
    /**
     * 加密 长数据加密(117)
     * @param array $originalData
     * @return string|void
     */
    private static function encrypt117($originalData,$rsaPublicKey){
        $crypto = '';
        $originalData = json_encode($originalData);
        foreach (str_split($originalData, 117) as $chunk) {

            openssl_public_encrypt($chunk, $encryptData, $rsaPublicKey);
            $crypto .= $encryptData;
        }
        return base64_encode($crypto);
    }

    /**
     * 解密 长数据解密(128)
     * @param $encryptData
     * @param $rsaPublicKey
     * @return string
     */
    private static function decrypt128($encryptData,$rsaPublicKey){
        $crypto = '';
        foreach (str_split(base64_decode($encryptData), 128) as $chunk) {

            openssl_public_decrypt($chunk, $decryptData, $rsaPublicKey);

            $crypto .= $decryptData;
        }
        return $crypto;
    }

}
